home *** CD-ROM | disk | FTP | other *** search
/ AMIGA-CD 2 / Amiga-CD - Volume 2.iso / ungepackte_daten / 1995 / 6 / 02 / c++-kurs / dirtree.c next >
C/C++ Source or Header  |  1995-06-01  |  6KB  |  205 lines

  1.  
  2. /* 
  3.  * DirTree.c © 1995 Clemens Marschner
  4.  * Implements Recursive Dir Tree class
  5.  */
  6.  
  7. #include "DirTree.h"
  8. #include <utility/tagitem.h>
  9.  
  10. struct BlockList *DirTree::SearchRek(char *sdir, char *pattern,
  11.       struct ExAllData *upperD, int rekurs) {
  12.    BPTR lock;
  13.    char *sbuffer = new char[512];      // nimmt Verzeichnisnamen auf
  14.    struct ExAllData *actual=0;
  15.    strncpy (sbuffer,sdir,512);
  16.    struct BlockList *blist=0, *rootlist=0;
  17.    if(rekurs == 0) running = TRUE;
  18.    rekurs++;
  19.       
  20.    if(lock = Lock(sdir, SHARED_LOCK)) 
  21.    {
  22.       if(blist = ReadDir(lock)) 
  23.       {
  24.          if(upperD) 
  25.          {
  26.             upperD->ed_downerB = (ULONG)blist;
  27.          } else 
  28.          {
  29.             rootlist = blist;
  30.          }
  31.          blist->upper = upperD; // wenn kein upperd, dann autom. init mit 0l
  32.          int dirinIt=0;
  33.          if(rekurs == 1) 
  34.             DirChanged(sdir);
  35.          for(actual = blist->ExAllData; actual; actual = actual->ed_Next) 
  36.          {
  37.             if(actual->ed_Type < 0)  {
  38.                long match;
  39.                match = MatchPatternNoCase(pattern,actual->ed_Name);
  40.                if(match) 
  41.                {
  42.                   FileFound(actual);
  43.                } else 
  44.                {
  45.                   long ioerr;
  46.                   if(ioerr = IoErr())
  47.                      PrintFault(ioerr,NULL);
  48.                }
  49.             }
  50.          }
  51.          for(actual = blist->ExAllData; actual; actual = actual->ed_Next) 
  52.          {
  53.             if (actual->ed_Type > 0) 
  54.             {
  55.                dirinIt=1;
  56.                if(actual->ed_Name) 
  57.                {
  58.                   if(!(AddPart(sbuffer,actual->ed_Name,512))) 
  59.                   {
  60.                      Error("DirTree: Fehler bei der Verzeichnisbehandlung durch Addpart\n");
  61.                   }
  62.                   DirChanged(sbuffer);
  63.                   SearchRek(sbuffer,pattern,actual,rekurs);
  64.                } 
  65.                STRPTR pp = PathPart(sbuffer);
  66.                *pp = '\0';
  67.             } 
  68.          }
  69.          if(!dirinIt &&  rekurs>1) 
  70.          {
  71.             DeleteDirBlock(blist);
  72.             if(upperD) 
  73.             {
  74.                upperD->ed_downerB = NULL;
  75.             }
  76.          }
  77.          if(!running) 
  78.          {
  79.             // Abbruch funktioniert nocht nicht richtig...
  80.             // liegt aber, blaub' ich, am Compiler
  81.             // for(...; actual, running; ...) liefert immer TRUE zurück 
  82.             // und bildet deshalb Endlosschleife
  83.             Error("Suchaktion abgebrochen.");
  84.          }
  85.       } else Error("DirTree: blist meldet Fehler\n");
  86.       UnLock(lock);
  87.    } else {
  88.       Fault(IoErr(), 0, sbuffer, FAULT_MAX);
  89.       Error(sbuffer);
  90.    }
  91.    rekurs--;
  92.    if(rekurs == 0) 
  93.       return rootlist;
  94.    delete sbuffer;
  95. }
  96.  
  97. void DirTree::DeleteDirBlock(struct BlockList *firstB) {
  98.    struct BlockList *actualB, *actualBCopy;
  99.    if(firstB) {
  100.       for(actualB=firstB; actualB;)  
  101.       {
  102.          if(actualB->ExAllDCopy) 
  103.          {
  104.             FreeVec(actualB->ExAllDCopy);
  105.             actualBCopy=actualB->next;
  106.             delete actualB;
  107.             actualB = actualBCopy;
  108.          } else actualB=NULL;
  109.       }
  110.    }
  111. }
  112.  
  113. void DirTree::DeleteAllBlocks(struct BlockList *firstB, 
  114.                                              struct ExAllData *upperD,int rekurs) 
  115. {
  116.    struct ExAllData *actual;  
  117.    rekurs++;
  118.    if(firstB) 
  119.    {
  120.       for(actual = firstB->ExAllData; actual; actual = actual->ed_Next) 
  121.       {
  122.          if(actual) 
  123.          {
  124.             if(actual->ed_Type > 0) 
  125.             {
  126.                DeleteAllBlocks((struct BlockList*)actual->ed_downerB, actual,rekurs);
  127.                //ndirs++;
  128.             } else //nfiles++;
  129.          }
  130.       }
  131.       DeleteDirBlock(firstB);
  132.    } 
  133.    rekurs--;
  134. }
  135.  
  136. struct BlockList *DirTree::ReadDir(BPTR lock) 
  137. {
  138.    BOOL goon=TRUE;
  139.    BOOL err=FALSE;
  140.    struct ExAllControl *eac;
  141.    struct BlockList *firstB,*actualB;
  142.  
  143.    eac = (struct ExAllControl*)AllocDosObject(DOS_EXALLCONTROL,TAG_DONE);
  144.    struct ExAllData *actualD;
  145.    int memcnt = 1;
  146.    ULONG bufsize = 48;
  147.             // könnte auch #defined werden, aber um variabel zu bleiben...
  148.    if(!eac)
  149.    {
  150.       Error("Recursive-Read: Error: Couldn't allocate DOS Object\n"); 
  151.       err = TRUE;
  152.    }
  153.    actualB = firstB = new struct BlockList; 
  154.    actualB->BufSize = bufsize * sizeof(struct ExAllData);   
  155.    actualB->ExAllDCopy = 
  156.       actualB->ExAllData = (struct ExAllData*)
  157.                                  AllocVec(actualB->BufSize,MEMF_ANY|MEMF_CLEAR);
  158.    while (goon && (!err)) 
  159.    {
  160.       if(actualB->ExAllDCopy == 0l) 
  161.       {
  162.          actualB->ExAllDCopy = actualB->ExAllData = NULL;
  163.          err = TRUE; goon = FALSE;
  164.          Error("Recursive-Read: Error: Not enough memory\n"); 
  165.       }
  166.       if(!err) 
  167.       {
  168.          (goon = ExAll(lock, actualB->ExAllData,
  169.                        actualB->BufSize,
  170.                        ED_DATE,eac));
  171.          actualD = actualB->ExAllData;
  172.          if(goon) 
  173.          { 
  174.             actualB->next = new struct BlockList; 
  175.             memcnt++;
  176.             actualB->next->BufSize = bufsize * (sizeof(struct ExAllData)-4);  
  177.             actualB->next->ExAllDCopy = 
  178.             actualB->next->ExAllData = (struct ExAllData*)
  179.                               AllocVec(actualB->BufSize,MEMF_ANY|MEMF_CLEAR);       
  180.             for(actualD = actualB->ExAllData; actualD->ed_Next; 
  181.                                                       actualD=actualD->ed_Next);
  182.             actualD->ed_Next = actualB->next->ExAllData; 
  183.                            // ist egtl. noch nicht def.
  184.             actualB = actualB->next;
  185.             actualB->next = NULL;
  186.          }
  187.       }
  188.    }  
  189.    if(firstB->ExAllData->ed_Name == NULL && firstB->ExAllData) 
  190.    {
  191.       FreeVec(firstB->ExAllData);
  192.       firstB->ExAllData = firstB->ExAllDCopy = NULL;
  193.    }
  194.    if(eac) FreeDosObject(DOS_EXALLCONTROL, eac); 
  195.    if(err) 
  196.    { 
  197.       DeleteDirBlock(firstB); 
  198.       return 0l; 
  199.    }
  200.    return firstB;
  201. }
  202.  
  203.  
  204.  
  205.